/**
 * 
 */
package com.homesoft.runtime.metadata.modle;

import java.math.BigDecimal;
import java.sql.Date;

/**
 * @author lihg extends ValueChangeNotifier
 */
public class DataType extends ValueChangeNotifier implements Cloneable {

	// 基础类型
	private BasicDataType _basicType;

	// 当基础类型是枚举、实体、javabean时，此字段存储类型的全名称
	private String _fullTypeName;

	// 是否集合
	private boolean _isCollection;

	public DataType() {
		this._isCollection = false;
	}

	// / <summary>
	// / 构造器
	// / </summary>
	// / <param name="basicType">基础数据类型</param>
	public DataType(BasicDataType basicType) {
		this._basicType = basicType;
		this._isCollection = false;
	}

	private DataType(DataType dataType) {
		this._basicType = dataType.getBasicType();
		this._isCollection = dataType.isCollection();
		this._fullTypeName = dataType.getFullTypeName();
	}

	// / <summary>
	// / 构造器
	// / </summary>
	// / <param name="basicType">基础数据类型</param>
	// / <param name="isCollection">是否集合</param>
	public DataType(BasicDataType basicType, boolean isCollection) {
		this._basicType = basicType;
		this._isCollection = isCollection;
	}

	// / <summary>
	// / 构造器
	// / </summary>
	// / <param name="basicType">基础数据类型</param>
	// / <param name="fullTypeName">类型全名称</param>
	public DataType(BasicDataType basicType, String fullTypeName) {
		this._basicType = basicType;
		this._fullTypeName = fullTypeName;
		this._isCollection = false;
	}

	// / <summary>
	// / 构造器
	// / </summary>
	// / <param name="basicType">基础数据类型</param>
	// / <param name="fullTypeName">类型全名称</param>
	// / <param name="isCollection">是否集合</param>
	public DataType(BasicDataType basicType, String fullTypeName, boolean isCollection) {
		this._basicType = basicType;
		this._fullTypeName = fullTypeName;
		this._isCollection = isCollection;
	}

	// / <summary>
	// / 获取或设置基础类型
	// / </summary>
	public BasicDataType getBasicType() {
		return _basicType;
	}

	public void setBasicType(BasicDataType value) {
		if (NotifyEnabled()) {
			BasicDataType oldValue = getBasicType();
			_basicType = value;
			OnPropertyChanged("BasicType", oldValue, value);
		} else {
			_basicType = value;
		}
	}

	// / <summary>
	// / 获取或设置类型全名称
	// / </summary>
	public String getFullTypeName() {
		return this._fullTypeName;
	}

	public void setFullTypeName(String value) {
		if (NotifyEnabled()) {
			String oldValue = _fullTypeName;
			_fullTypeName = value;
			OnPropertyChanged("FullTypeName", oldValue, value);
		} else {
			_fullTypeName = value;
		}
	}

	// / <summary>
	// / 获取或设置是否集合或数组
	// / </summary>
	public boolean isCollection() {
		return this._isCollection;
	}

	public void setCollection(boolean value) {
		if (NotifyEnabled()) {
			boolean oldValue = _isCollection;
			this._isCollection = value;
			OnPropertyChanged("IsCollection", oldValue, value);
		} else {
			this._isCollection = value;
		}
	}

	// / <summary>
	// / 获取DataType中BasicType所对应的运行期类型的名称
	// / </summary>
	// / <returns></returns>
	public String getBasicRuntimeTypeName() {
		switch (this.getBasicType()) {
		case Integer:
			return int.class.getName();
		case Long:
			return long.class.getName();
		case Double:
			return double.class.getName();
		case DateTime:
			return Date.class.getName();
		case Char:
			return char.class.getName();
		case Boolean:
			return boolean.class.getName();
		case String:
		case StringClob:
			return String.class.getName();
		case EncryptString:
			return "GTP.Runtime.DataObject.EncryptStr.EncryptString";
		case Decimal:
			return BigDecimal.class.getName();
		case BinaryBlob:
		case Binary:
			return byte[].class.getName();
		case DataDict:
			return "GTP.Runtime.DataObject.DataDict";
		case GTPEnum:
		case Entity:
		case RuntimeClass:
		case Poco:
		case Query:
		default:
			return this.getFullTypeName();
		}
	}

	// / <summary>
	// / 获取基本类型的运行期类型。GTPEnum，Entity，RuntimeClass始终返回null
	// / </summary>
	public Class getBasicRuntimeType() {
		switch (this.getBasicType()) {
		case Integer:
			return int.class;
		case Long:
			return long.class;
		case Double:
			return double.class;
		case DateTime:
			return Date.class;
		case Char:
			return char.class;
		case Boolean:
			return boolean.class;
		case String:
		case StringClob:
		case EncryptString:
			return String.class;
		case Decimal:
			return BigDecimal.class;
		case BinaryBlob:
		case Binary:
			return byte[].class;
		case DataDict:
		case GTPEnum:
		case Entity:
		case Poco:
		case Query:
		case RuntimeClass:
		default:
			return null;
		}
	}

	public String toString() {
		String result;
		switch (this.getBasicType()) {
		case GTPEnum:
		case Entity:
		case Poco:
		case Query:
		case RuntimeClass:
			result = this.getFullTypeName();
			break;
		default:
			result = this.getBasicType().toString();
			break;
		}
		return result;
	}

	public DataType clone() {
		return new DataType(this);
	}

	public void Assign(DataType dataType) {
		this._basicType = dataType.getBasicType();
		this._isCollection = dataType.isCollection();
		this._fullTypeName = dataType.getFullTypeName();
	}

	public boolean Equals(Object obj) {
		if (!(obj instanceof DataType)) {
			return false;
		}
		if (this.getBasicType() == ((DataType) obj).getBasicType()) {
			return true;
		}
		return false;
	}
}
